# -*- coding: utf-8 -*-
# created on 2017/01/05
# 

from mathsolver.functions.base import *
from mathsolver.functions.base.base import new_latex
from mathsolver.functions.process import ProcessExpression
from sympy import Abs
from mathsolver.functions.xiangliang.basic import XLJudgeAxis


class XLGetUnitVectorS001(BaseFunction):
    """
    坐标法：求单位向量, 不含equations
    已知向量\\overrightarrow{a}=(1 ,0),\\overrightarrow{b}=(1,1),求2\\overrightarrow{a}+\\overrightarrow{b}的单位向量.
    """
    def solver(self, *args):
        assert len(args) == 1
        known = self.known
        if 'Vequations' in known:
            veqs = known['Vequations']
            assert not veqs
        target = args[0].sympify()
        flag = XLJudgeAxis(known).solver(target).output[0].sympify()
        assert flag
        answer = ProcessExpression(known).solver(args[0]).output[0].sympify()
        self.steps.append(["", "∴ %s = %s" % (new_latex(target), new_latex(answer))])
        unit_vector_s = [target / Abs(target), -target / Abs(target)]
        new_unit_vector_s = []
        for UnitVector in unit_vector_s:
            new_unit_vector = ProcessExpression(known).solver(BaseExpression(str(UnitVector))).output[0].sympify()
            new_unit_vector_s.append(new_unit_vector)
        self.steps.append(["", "∴%s单位向量为%s" % (new_latex(target), ",".join([new_latex(v) for v in new_unit_vector_s]))])
        self.output.append(BaseVectors(new_unit_vector_s))
        self.label.add("求向量的单位向量-坐标法")
        return self


class XLGetUnitVectorS002(BaseFunction):
    """
    # 坐标法：求单位向量
    # 不含equations, 向量名含两个字母
    已知点A(1,3),B(4,-1),求向量\\overrightarrow{AB}的单位向量为 ()
    """
    def solver(self, *args):
        assert len(args) == 1
        known = self.known
        assert 'Vequations' not in known
        assert isinstance(args[0], BaseVector)
        vector = sympify(args[0].value)
        vector_name = vector.args[0]
        assert len(str(vector_name)) == 2
        vector_axis_name = str("Axis_")
        vector_axis_name += str(vector_name)
        if vector_axis_name in self.known:
            pass
        else:
            left_p, right_p = str(vector_name)
            if left_p in self.known:
                left_p_value = self.search(left_p)
                left_p_value = left_p_value.sympify()
            else:
                raise Exception("to do")
            if right_p in self.known:
                right_p_value = self.search(right_p)
                right_p_value = right_p_value.sympify()
            else:
                raise Exception("to do")
            vector_value = (right_p_value[0] - left_p_value[0], right_p_value[1] - left_p_value[1])
            known[vector_axis_name] = vector_value
        answer = ProcessExpression(known).solver(args[0]).output[0].sympify()
        self.steps.append(["", "∴ %s = %s" % (new_latex(vector), new_latex(answer))])
        unit_vector_s = [vector / Abs(vector), -vector / Abs(vector)]
        new_unit_vector_s = []
        for UnitVector in unit_vector_s:
            new_unit_vector = ProcessExpression(known).solver(BaseExpression(str(UnitVector))).output[0].sympify()
            new_unit_vector_s.append(new_unit_vector)
        self.steps.append(["", "∴%s单位向量为%s" % (new_latex(vector), ",".join([new_latex(v) for v in new_unit_vector_s]))])
        self.output.append(BaseVectors(new_unit_vector_s))
        self.label.add("求向量的单位向量-坐标法")
        return self


class XLGetUnitVectorS(BaseFunction):
    CLS = [XLGetUnitVectorS001, XLGetUnitVectorS002]

    def solver(self, *args):
        known = self.known
        r = None
        for cl in XLGetUnitVectorS.CLS:
            try:
                new_known = dict(known)
                r = cl(new_known, verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r


class XLGetUnitVector(BaseFunction):
    """
    已知向量\\overrightarrow{a}=(1 ,0),\\overrightarrow{b}=(1,1),
    则与2\\overrightarrow{a}+\\overrightarrow{b}同向的单位向量的坐标表示为
    """
    def solver(self, *args):
        assert len(args) == 2
        if isinstance(args[0], BaseVector):
            target = sympify(args[0].value)
        else:
            target = args[0].sympify()
        text = args[1]
        new_known1 = dict(self.known)
        stepsolver1 = XLGetUnitVectorS(new_known1).solver(args[0])
        self.steps += stepsolver1.steps
        self.label.update(stepsolver1.label)
        unit_vector_s = stepsolver1.output[0].sympify()
        from mathsolver.functions.xiangliang.Vector_GetExpress import XLGetExpress
        new_known2 = dict(self.known)
        new_target = XLGetExpress(new_known2).solver(args[0]).output[0].sympify()
        target_unit_vector = None
        if text.find("同向") >= 0 or text.find("同方向") >= 0:
            for UnitVector in unit_vector_s:
                if new_target[0] * UnitVector[0] > 0:
                    target_unit_vector = UnitVector
                    self.steps.append(["", "与%s同向的单位向量为(%s, %s)" % (
                        new_latex(target), new_latex(UnitVector[0]), new_latex(UnitVector[1]))])
        assert target_unit_vector
        self.output.append(BaseVector(target_unit_vector))
        return self


def get_vector_xiangs(expr):
    p1 = r'Abs_[a-zA-Z]'
    m1 = re.findall(p1, str(expr))
    m1 = list(set(m1))
    p2 = r'Angle_[a-zA-Z][a-zA-Z]'
    m2 = re.findall(p2, str(expr))
    m2 = list(set(m2))
    m = m1 + m2
    return m


# class XLGetExpress(BaseFunction):
#     def solver(self, *args):
#         target = args[0].sympify()
#         target = target.expand()
#         abs_a = sympify('Abs_a')
#         abs_b = sympify('Abs_b')
#         angle_ab = sympify('Angle_ab')
#         new_target = 2 * abs_a * abs_b * cos(angle_ab * pi / 180) - abs_b * abs_b
#         target_xiangs = get_vector_xiangs(new_target)
#         assert target_xiangs
#         for target_xiang in target_xiangs:
#             new_item = sympify(target_xiang)
#             new_item_value = self.search(target_xiang)
#             new_target = new_target.subs({new_item: new_item_value})
#         new_target = simplify(new_target)
#         self.steps.append(["", "∴%s = %s" % (new_latex(target), new_latex(new_target))])
#         self.output.append(BaseNumber(new_target))
#         return self
